package com.h3bpm.kumhosunny.knowledge.controller;

import OThinker.Common.DotNetToJavaStringHelper;
import OThinker.Common.Organization.Models.OrgPost;
import OThinker.Common.Organization.Models.OrgStaff;
import OThinker.Common.Organization.Models.User;
import OThinker.H3.Controller.ControllerBase;
import OThinker.H3.Controller.ViewModels.ActionResult;
import OThinker.H3.Entity.DataModel.BizObject;
import OThinker.H3.Entity.Instance.Data.InstanceData;
import OThinker.H3.Portal.webservices.BPMService;
import OThinker.H3.Portal.webservices.Entity.BPMServiceResult;
import OThinker.H3.Portal.webservices.Entity.DataItemParam;
import OThinker.H3.Portal.webservices.impl.BPMServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.h3bpm.base.util.AppUtility;
import com.h3bpm.kumhosunny.common.H3Property;
import com.h3bpm.kumhosunny.common.utils.DateTableUtil;
import com.h3bpm.kumhosunny.common.utils.SqlUtil;
import com.h3bpm.kumhosunny.knowledge.beans.PageSearch;
import com.h3bpm.kumhosunny.knowledge.enums.Knowledge;
import data.DataRow;
import data.DataTable;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletResponse;
import java.net.URI;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;

/**
 * @author zhengyj
 * @date 2019/8/19
 * @description 研发知识平台控制器
 */
@Controller
@RequestMapping("/Portal/kumhosunny/knowledge")
public class KnowledgeController extends ControllerBase {

    private static final Logger LOGGER = LoggerFactory.getLogger(ControllerBase.class);


    private  final String ONE="1";

    private  final String TOW="2";
    private  final String UNDEFINED="undefined";

    /**
     * 知识新增流程
     */
    private final static String MATERIALTRAITBYCREATE =  "materialTraitByCreate";


    private BPMService bpmService = new BPMServiceImpl();

    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public String getFunctionCode() {
        return null;
    }

    /****
     * 功能描述: 知识新增流程完成后。新增知识。采用方式，取知识新增流程数据来自动发起 知识数据流程  ，知识数据流程不需要审批。来实现数据保存功能。
     *
     * @Param: [instanceId]
     * @Return: void
     * @Author: zhengyj
     * @Date: 2019/8/20 9:09
     */
    @RequestMapping(value = "/createKnowledge",  method = {RequestMethod.POST,RequestMethod.GET},produces = "text/html;charset=UTF-8")
    @ResponseBody
    public void createKnowledge(String instanceId){

        LOGGER.warn("=======创建知识数据==========Start========instanceId:" + instanceId);

        try {
            InstanceData instanceData = new InstanceData(getEngine(),instanceId, User.AdministratorID);

            createKnowledgeByDeatil(instanceData);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /****
     * 功能描述: 根据 知识-新增 流程 发起 知识数据流程。保存数据
     * 
     * @Param: [instanceData]
     * @Return: void 
     * @Author: zhengyj
     * @Date: 2019/8/20 11:36
     */
    private void createKnowledgeByDeatil(InstanceData instanceData) throws Exception {

        HashMap<String, Object> valueTable = instanceData.getBizObject().getValueTable();
        List<DataItemParam> createParams = new ArrayList<>();
        // 处理类型是短文本的数据项
        for (String key : valueTable.keySet()) {
            if (!H3Property.BASEDTO.contains(key) && valueTable.get(key) instanceof String) {
                createParams.add(new DataItemParam(key,valueTable.get(key)));
            }
        }
        // 处理子表
        BizObject[] detailTable = (BizObject[])valueTable.get(MATERIALTRAITBYCREATE);
        if ( null != detailTable) {
            List<HashMap<String,Object>> detailValueList = new ArrayList<>();
            for (BizObject detail : detailTable) {
                HashMap<String,Object> detailValue = new HashMap<>(2);
                HashMap<String, Object> detailValueTable = detail.getValueTable();
                detailValue.put(Knowledge.paramName.name(),detailValueTable.get(Knowledge.paramName.name()));
                detailValue.put(Knowledge.paramAttribute.name(),detailValueTable.get(Knowledge.paramAttribute.name()));
                detailValue.put(Knowledge.paramType.name(),detailValueTable.get(Knowledge.paramType.name()));
                detailValue.put(Knowledge.testCondition.name(),detailValueTable.get(Knowledge.testCondition.name()));
                detailValue.put(Knowledge.paramMin.name(),detailValueTable.get(Knowledge.paramMin.name()));
                detailValue.put(Knowledge.paramMax.name(),detailValueTable.get(Knowledge.paramMax.name()));
                detailValueList.add(detailValue);
            }
            createParams.add(new DataItemParam(Knowledge.materialTrait.name(),detailValueList));
        }
        // 处理附件，附件赋值方式比较特殊，此处采用，先发起流程再上传附件。
        User user = (User)getEngine().getOrganization().GetUnit(instanceData.getBizObject().getOwnerId());
        LOGGER.info("====== 发起知识数据流程=========发起人:" + user.getName() );
        BPMServiceResult bpmServiceResult = bpmService.StartWorkflow(H3Property.SYSTEMCODE,H3Property.SECRET,Knowledge.knowledge.name(),user.getCode(),true,createParams);
        if (bpmServiceResult.isSuccess()) {
            // 方便区分，将 知识-新增 流程 为 父流程， 知识数据流程为子流程
            String childInstanceId = bpmServiceResult.getInstanceId();
            InstanceData childnstanceData = new InstanceData(getEngine(),childInstanceId, User.AdministratorID);

            // 复制 附件 ，最后参数 是否重写。
            AppUtility.getEngine().getBizObjectManager().CopyAttachments(instanceData.getSchemaCode(),instanceData.getBizObject().getObjectID(),Knowledge.document.name(),
                    childnstanceData.getSchemaCode(),childnstanceData.getBizObject().getObjectID(),Knowledge.document.name(),true);
        }

    }

    /**
     * 加载 知识数据
     *
     * @return
     */
    @RequestMapping(value = "/searchData", produces = "application/json;charset=utf-8", method = RequestMethod.GET)
    @ResponseBody
    public ActionResult searchData(PageSearch pageSearch,String industry,String subIndustry,String parts) {
        ActionResult actionResult = new ActionResult(true);
        int start = pageSearch.getPageStart();
        int end = start + pageSearch.getPageSize();
        try {
            String whereSql = "where nowState = 0";
            if (!DotNetToJavaStringHelper.isNullOrEmpty(pageSearch.getSearchKey())) {
                whereSql = whereSql + " and documentName like '%" +  pageSearch.getSearchKey() + "%'  ";
            }
            if (!DotNetToJavaStringHelper.isNullOrEmpty(industry)) {
                whereSql = whereSql + " and trade like '%" +  industry + "%'  ";
            }
            if (!DotNetToJavaStringHelper.isNullOrEmpty(subIndustry)) {
                whereSql = whereSql + " and product like '%" + subIndustry + "%'  ";
            }
            if (!DotNetToJavaStringHelper.isNullOrEmpty(parts)) {
                whereSql = whereSql + " and spareParts like '%" + parts + "%'  ";
            }
            //先查询总数
            String queryCount = String.format("select count(*) from I_knowledge %s ", whereSql);
            DataTable dataTable = SqlUtil.doQuery(queryCount);
            actionResult.setLoadData(dataTable.getRows().size() > 0 ? dataTable.getRows().get(0).getString(0) : "0");

            // 在查询内容
            String query = String.format("SELECT documentName,trade,product,spareParts,formingMethod,brandName,b.FinishTime,b.OriginatorName,b.Originator,b.ObjectID as instanceId from i_knowledge a INNER JOIN ot_instancecontext b on a.ObjectID = b.BizObjectId  %s order by b.FinishTime desc limit %s,%s",
                    whereSql, start, end);
            dataTable = SqlUtil.doQuery(query);
            actionResult.setExtend(DateTableUtil.getRowList(dataTable));
        } catch (Exception e) {
            actionResult.setSuccess(false);
            actionResult.setMessage(e.getMessage());

        }
        return actionResult;
    }
    /**
     * 加载 知识数据
     *
     * @return
     */
    @RequestMapping(value = "/searchDataBySenior", produces = "application/json;charset=utf-8", method = RequestMethod.GET)
    @ResponseBody
    public ActionResult searchDataBySenior(PageSearch pageSearch) {
        ActionResult actionResult = new ActionResult(true);
        int start = pageSearch.getPageStart();
        int end = start + pageSearch.getPageSize();
        try {
            BASE64Decoder base64Decoder = new BASE64Decoder();
            String dataSql = new String(base64Decoder.decodeBuffer(pageSearch.getSearchSql()),H3Property.UTF_8);
            if(!DotNetToJavaStringHelper.isNullOrEmpty(dataSql)){
                //先查询总数
                LOGGER.info("=====原sql=====" + dataSql);
                String queryCount = String.format("select COUNT(tableA.documentName) from  ( %s ) tableA", dataSql);
                DataTable dataTable = SqlUtil.doQuery(queryCount);
                actionResult.setLoadData(dataTable.getRows().size() > 0 ? dataTable.getRows().get(0).getString(0) : "0");

                // 在查询内容
                String query = String.format("SELECT * from  ( %s ) tableA order by FinishTime desc limit %s,%s",
                        dataSql, start, end);
                LOGGER.info("=====知识数据高级搜索=====" + query);
                dataTable = SqlUtil.doQuery(query);
                actionResult.setExtend(DateTableUtil.getRowList(dataTable));
            }
        } catch (Exception e) {
            actionResult.setSuccess(false);
            actionResult.setMessage(e.getMessage());

        }
        return actionResult;
    }


    /****
     * 功能描述: 创建 知识数据删除流程
     *
     * @Param: [knowledgeInstanceId, response]
     * @Return: void
     * @Author: zhengyj
     * @Date: 2019/8/22 15:23
     */
    @RequestMapping(value = "/createKnowledgeDeleteProcess", produces = "application/json;charset=utf-8", method = RequestMethod.GET)
    @ResponseBody
    public void createKnowledgeDeleteProcess(String knowledgeInstanceId,HttpServletResponse response) {
        LOGGER.warn("=======创建知识数据删除流程===========knowledgeInstanceId:" + knowledgeInstanceId);
        try {
            InstanceData knowledgeInstanceData = new InstanceData(getEngine(),knowledgeInstanceId, User.AdministratorID);

            List<DataItemParam> createParams = new ArrayList<>();
            createParams.add(new DataItemParam(Knowledge.documentName.name(),knowledgeInstanceData.getItem(Knowledge.documentName.name()).getValue()));
            createParams.add(new DataItemParam("documentId",knowledgeInstanceData.getBizObject().getObjectID()));
            User user = (User)getEngine().getOrganization().GetUnit(knowledgeInstanceData.getBizObject().getOwnerId());
            LOGGER.info("====== 发起知识数据删除流程=========发起人:" + user.getName() );
            BPMServiceResult bpmServiceResult = bpmService.StartWorkflow(H3Property.SYSTEMCODE,H3Property.SECRET,"knowledgeDeleteProcess",user.getCode(),false,createParams);
            if (bpmServiceResult.isSuccess()) {
                Thread.sleep(500);
                String workItemId = SqlUtil.doQuery(String.format("select  objectid from OT_workitem where instanceId = '%s' and ActivityCode = 'Activity2' and Participant = '%s' limit 1",bpmServiceResult.getInstanceId(),user.getObjectID())).getRows().get(0).getString(0);
                response.sendRedirect("/Portal/WorkItemSheets.html?WorkItemID=" + workItemId);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 判断角色是否允许 查看文档
     *
     * @return
     */
    @RequestMapping(value = "/adjustRole", produces = "application/json;charset=utf-8", method = RequestMethod.GET)
    @ResponseBody
    public ActionResult adjustRole(String userId,String roles) {
        ActionResult actionResult = new ActionResult(true);
        actionResult.setExtend(false);

        String[] roleStrArray = roles.split(";");
        try {
            // 若是管理员  返回
            if (getEngine().getOrganization().IsAdministrator(userId)) {
                actionResult.setExtend(true);
                return actionResult;
            }
            // 判断是否 属于 角色下。
            for (String role : roleStrArray) {
               OrgPost post = getEngine().getOrganization().GetJobByCode(role);
               if (null != post) {
                   List<OrgStaff> orgStaffList = post.getChildList();
                   for (OrgStaff orgStaff : orgStaffList) {
                       if (userId.equals(orgStaff.getUserID())) {
                           actionResult.setExtend(true);
                           break;
                       }
                   }
               }
            }

        } catch (Exception e) {
            actionResult.setExtend(false);
        }
        return actionResult;
    }

    @RequestMapping(value = "/getIndustry",  method = {RequestMethod.POST,RequestMethod.GET})
    @ResponseBody
    public JSONObject getIndustry(String type,String value){

        JSONObject obj =new JSONObject();
        obj.put("status","200");
        JSONArray array = new JSONArray();
        array.add("");
        try {
        if(type!=null &&  ONE.equals(type)){
            if(value==null || "".equals(value)  || UNDEFINED.equals(value)){
                String getIndustrySql="select distinct product  from i_treadline ";
                DataTable dataTable =  SqlUtil.doQuery(getIndustrySql);
                for(DataRow dataRow :dataTable.getEntityRows() ){
                    array.add( dataRow.getString("product"));
                }
            }else{
                String getIndustrySql="select distinct product  from i_treadline where trade='"+value+"'";
                DataTable dataTable =  SqlUtil.doQuery(getIndustrySql);
                for(DataRow dataRow :dataTable.getEntityRows() ){
                    array.add( dataRow.getString("product"));
                }
            }

            }else if(type!=null && TOW.equals(type)){

            if(value==null || "".equals(value)  || UNDEFINED.equals(value)){
                String getIndustrySql="select distinct spareParts  from i_treadline ";
                DataTable dataTable =  SqlUtil.doQuery(getIndustrySql);
                for(DataRow dataRow :dataTable.getEntityRows() ){
                    array.add( dataRow.getString("spareParts"));
                }
            }else{
                String getIndustrySql="select distinct spareParts  from i_treadline where product='"+value+"'";
                DataTable dataTable =  SqlUtil.doQuery(getIndustrySql);
                for(DataRow dataRow :dataTable.getEntityRows() ){
                    array.add( dataRow.getString("spareParts"));
                }
            }
       }else{
           String getIndustrySql="select distinct trade  from i_treadline ";
               DataTable dataTable =  SqlUtil.doQuery(getIndustrySql);
             for(DataRow dataRow :dataTable.getEntityRows() ){
                  dataRow.getString("trade");
                 array.add( dataRow.getString("trade"));
             }

       }

            obj.put("data",array );
        } catch (Exception e) {
            obj.put("status","200");
            e.printStackTrace();
        }
        return obj;
    }



}
